/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.navigator;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import junit.framework.TestCase;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.navigator.PipelinedShapeModification;
import org.eclipse.ui.navigator.PipelinedViewerUpdate;
import org.python.pydev.core.IPythonPathNature;
import org.python.pydev.core.TestDependent;
import org.python.pydev.navigator.elements.IWrappedResource;
import org.python.pydev.navigator.elements.PythonFolder;
import org.python.pydev.navigator.elements.PythonProjectSourceFolder;
import org.python.pydev.navigator.elements.PythonSourceFolder;
import org.python.pydev.plugin.nature.PythonNature;
import com.aptana.shared_core.callbacks.ICallback;
@SuppressWarnings("unchecked")
public class PythonModelProviderTest extends TestCase {
public static void main(String[] args) {
try {
PythonModelProviderTest test = new PythonModelProviderTest();
test.setUp();
test.testFolderToSourceFolder();
test.tearDown();
System.out.println("OK");
junit.textui.TestRunner.run(PythonModelProviderTest.class);
} catch (Throwable e) {
e.printStackTrace();
}
}
protected void setUp() throws Exception {
super.setUp();
PythonNature.IN_TESTS = true;
}
protected void tearDown() throws Exception {
super.tearDown();
PythonNature.IN_TESTS = false;
}
private ProjectStub project;
private FileStub file;
private PythonModelProvider provider;
/**
* Test if intercepting an add deep within the pythonpath structure will correctly return an object
* from the python model.
*/
public void testInterceptAdd() throws Exception {
PythonNature nature = createNature(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source/python");
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature);
file = new FileStub(project, new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC
+ "projroot/source/python/pack1/pack2/mod2.py"));
provider = new PythonModelProvider();
HashSet<Object> files = new HashSet<Object>();
files.add(file);
files.add(null);
files.add("string");
provider.interceptAdd(new PipelinedShapeModification(file.getParent(), files));
assertEquals(2, files.size());
for (Object wrappedResource : files) {
assertTrue((wrappedResource instanceof IWrappedResource && ((IWrappedResource) wrappedResource)
.getActualObject() == file) || wrappedResource.equals("string"));
}
}
/**
* Test if intercepting an object that does not have a parent works.
*/
public void testInterceptRefresh() throws Exception {
PythonNature nature = createNature(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source/python");
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature);
provider = new PythonModelProvider();
PipelinedViewerUpdate update = new PipelinedViewerUpdate();
Set<Object> refreshTargets = update.getRefreshTargets();
refreshTargets.add(project);
refreshTargets.add(null);
refreshTargets.add("string");
provider.interceptRefresh(update);
assertEquals(2, refreshTargets.size());
for (Object wrappedResource : refreshTargets) {
assertTrue(wrappedResource == project || wrappedResource.equals("string"));
}
}
/**
* Test if setting the project root as a source folder will return an object from the python model.
*/
public void testProjectIsRoot2() throws Exception {
String pythonpathLoc = TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot";
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(pythonpathLoc);
PythonNature nature = createNature(pythonPathSet);
WorkspaceRootStub workspaceRootStub = new WorkspaceRootStub();
project = new ProjectStub(new File(pythonpathLoc), nature);
provider = new PythonModelProvider();
FolderStub folder = new FolderStub(project,
new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source"));
workspaceRootStub.addChild(project);
project.setParent(workspaceRootStub);
HashSet<Object> folders = new HashSet<Object>();
folders.add(folder);
PipelinedShapeModification addModification = new PipelinedShapeModification(project, folders);
addModification.setParent(project);
provider.interceptAdd(addModification);
assertEquals(1, addModification.getChildren().size());
//it should've been wrapped
assertTrue(addModification.getChildren().iterator().next() instanceof IWrappedResource);
}
/**
* Test if setting the project root as a source folder will return an object from the python model.
*/
public void testProjectIsRoot() throws Exception {
String pythonpathLoc = TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot";
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(pythonpathLoc);
PythonNature nature = createNature(pythonPathSet);
WorkspaceRootStub workspaceRootStub = new WorkspaceRootStub();
project = new ProjectStub(new File(pythonpathLoc), nature);
provider = new PythonModelProvider();
workspaceRootStub.addChild(project);
workspaceRootStub.addChild(null);
workspaceRootStub.addChild("other");
project.setParent(workspaceRootStub);
Object[] children1 = provider.getChildren(workspaceRootStub);
assertEquals(2, children1.length);
int stringsFound = 0;
int projectSourceFoldersFound = 0;
for (Object c : children1) {
if (c instanceof String) {
stringsFound += 1;
} else if (c instanceof PythonProjectSourceFolder) {
projectSourceFoldersFound += 1;
} else {
fail("Expecting source folder or string. Received: " + c.getClass().getName());
}
}
assertEquals(1, stringsFound);
assertEquals(1, projectSourceFoldersFound);
//now, let's go and change the pythonpath location to a folder within the project and see if it changes...
pythonPathSet.clear();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source/python");
IResource refreshObject = provider.internalDoNotifyPythonPathRebuilt(project, new ArrayList<String>(
pythonPathSet));
assertTrue("Expecting the refresh object to be the root and not the project",
refreshObject instanceof IWorkspaceRoot);
children1 = provider.getChildren(workspaceRootStub);
assertEquals(2, children1.length);
stringsFound = 0;
int projectsFound = 0;
for (Object c : children1) {
if (c instanceof String) {
stringsFound += 1;
} else if (c instanceof IProject) {
projectsFound += 1;
} else {
fail("Expecting source folder or string. Received: " + c.getClass().getName());
}
}
assertEquals(1, stringsFound);
assertEquals(1, projectsFound);
//set to be the root again
pythonPathSet.clear();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot");
refreshObject = provider.internalDoNotifyPythonPathRebuilt(project, new ArrayList<String>(pythonPathSet));
assertTrue("Expecting the refresh object to be the root and not the project",
refreshObject instanceof IWorkspaceRoot);
}
/**
* Creates a nature that has the passed pythonpath location in its pythonpath.
*/
private PythonNature createNature(String pythonpathLoc) {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(pythonpathLoc);
return createNature(pythonPathSet);
}
/**
* Creates a nature that has the given set as its underlying pythonpath paths. The reference
* is kept inside as a reference, so, changing that reference will affect the pythonpath
* that is set in the nature.
*/
private PythonNature createNature(final HashSet<String> pythonPathSet) {
PythonNature nature = new PythonNature() {
@Override
public IPythonPathNature getPythonPathNature() {
return new PythonPathNatureStub(pythonPathSet);
}
};
return nature;
}
/**
* Test if changing the pythonpath has the desired effects in the python model.
*/
public void testPythonpathChanges() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
pythonPathSet.add("invalid");
PythonNature nature = createNature(pythonPathSet);
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature, true);
provider = new PythonModelProvider();
Object[] children1 = provider.getChildren(project);
assertTrue(children1[0] instanceof PythonSourceFolder);
//no changes in the pythonpath
provider.internalDoNotifyPythonPathRebuilt(project, new ArrayList<String>(pythonPathSet));//still the same
Object[] children2 = provider.getChildren(project);
assertEquals(1, children1.length);
assertEquals(1, children2.length);
assertSame(children1[0], children2[0]);
//changed pythonpath (source folders should be removed)
pythonPathSet.clear();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source/python");
provider.internalDoNotifyPythonPathRebuilt(project, new ArrayList<String>(pythonPathSet));
Object[] children3 = provider.getChildren(project);
assertFalse(children3[0] instanceof PythonSourceFolder);
//restore initial
pythonPathSet.clear();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
Object[] children4 = provider.getChildren(project);
assertTrue(children4[0] instanceof PythonSourceFolder);
assertNotSame(children1[0], children4[0]); //because it was removed
}
public void testDontRemoveOtherPluginElements() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
PythonNature nature = createNature(pythonPathSet);
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature);
provider = new PythonModelProvider();
HashSet<Object> currentChildren = new HashSet<Object>();
currentChildren.add("Test");
provider.getPipelinedChildren(project, currentChildren);
assertEquals(1, currentChildren.size());
assertEquals("Test", currentChildren.iterator().next());
Object[] children = provider.getChildren(project);
currentChildren.addAll(Arrays.asList(children));
provider.getPipelinedChildren(project, currentChildren);
assertEquals(2, currentChildren.size()); //Test + source folder
boolean found = false;
for (Object o : currentChildren) {
if ("Test".equals(o)) {
found = true;
} else {
assertTrue(o instanceof PythonSourceFolder);
}
}
if (!found) {
fail("Could not find generated child");
}
}
public void testCreateChildrenInWrappedResource() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"); //root is the source
PythonNature nature = createNature(pythonPathSet);
WorkspaceRootStub workspaceRootStub = new WorkspaceRootStub();
ArrayList<Object> additionalChildren = new ArrayList<Object>();
additionalChildren.add("string");
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature, true,
additionalChildren);
workspaceRootStub.addChild(project);
project.setParent(workspaceRootStub);
provider = new PythonModelProvider();
HashSet<Object> currentChildren = new HashSet<Object>();
currentChildren.add(project);
currentChildren.add(null);
provider.getPipelinedChildren(workspaceRootStub, currentChildren);
assertEquals(1, currentChildren.size());
PythonProjectSourceFolder projectSourceFolder = (PythonProjectSourceFolder) currentChildren.iterator().next();
currentChildren = new HashSet<Object>();
currentChildren.add(null);
provider.getPipelinedChildren(projectSourceFolder, currentChildren);
assertEquals(2, currentChildren.size());
}
public void testNullElements() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"); //root is the source
PythonNature nature = createNature(pythonPathSet);
WorkspaceRootStub workspaceRootStub = new WorkspaceRootStub();
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature);
workspaceRootStub.addChild(project);
project.setParent(workspaceRootStub);
provider = new PythonModelProvider();
HashSet<Object> currentChildren = new HashSet<Object>();
currentChildren.add(project);
currentChildren.add(null);
provider.getPipelinedChildren(workspaceRootStub, currentChildren);
assertEquals(1, currentChildren.size());
PythonProjectSourceFolder projectSourceFolder = (PythonProjectSourceFolder) currentChildren.iterator().next();
currentChildren = new HashSet<Object>();
currentChildren.add(null);
currentChildren.add(null);
provider.getPipelinedChildren(projectSourceFolder, currentChildren);
assertEquals(1, currentChildren.size());
}
public void testAddSourceFolderToSourceFolder() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
String source2Folder = TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source2";
File f = new File(source2Folder);
if (f.exists()) {
f.delete();
}
pythonPathSet.add(source2Folder); //still not created!
PythonNature nature = createNature(pythonPathSet);
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature, false);
provider = new PythonModelProvider();
Object[] children1 = provider.getChildren(project);
assertEquals(1, children1.length);
assertTrue(children1[0] instanceof PythonSourceFolder);
Set set = new HashSet();
f.mkdir();
try {
FolderStub source2FolderFile = new FolderStub(project, f);
set.add(source2FolderFile);
provider.interceptAdd(new PipelinedShapeModification(project, set));
assertEquals(1, set.size());
assertTrue(set.iterator().next() instanceof PythonSourceFolder);
} finally {
f.delete();
}
}
public void testFolderToSourceFolder() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
String source2Folder = TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source2";
File f = new File(source2Folder);
File f1 = new File(f, "childFolder");
if (f1.exists()) {
f1.delete();
}
if (f.exists()) {
f.delete();
}
pythonPathSet.add(source2Folder); //still not created!
PythonNature nature = createNature(pythonPathSet);
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature, false);
provider = new PythonModelProvider();
Object[] children1 = provider.getChildren(project);
assertEquals(1, children1.length);
assertTrue("Found: " + children1[0], children1[0] instanceof PythonSourceFolder);
f.mkdir();
f1.mkdir();
try {
FolderStub source2FolderFile = new FolderStub(project, f);
FolderStub source2FolderChild = new FolderStub(project, source2FolderFile, f1);
Set set = new HashSet();
set.add(source2FolderChild);
provider.interceptAdd(new PipelinedShapeModification(source2FolderFile, set));
assertEquals(1, set.size());
PythonFolder c = (PythonFolder) set.iterator().next();
PythonSourceFolder sourceFolder = c.getSourceFolder();
assertTrue(sourceFolder instanceof PythonSourceFolder);
set.clear();
set.add(source2FolderChild);
provider.interceptAdd(new PipelinedShapeModification(source2FolderFile, set));
} finally {
f1.delete();
f.delete();
}
}
public void testFolderToSourceFolder2() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
String source2Folder = TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source2";
File f = new File(source2Folder);
File f1 = new File(f, "childFolder");
File f2 = new File(f1, "rechildFolder");
if (f2.exists()) {
f2.delete();
}
if (f1.exists()) {
f1.delete();
}
if (f.exists()) {
f.delete();
}
pythonPathSet.add(source2Folder); //still not created!
PythonNature nature = createNature(pythonPathSet);
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature, false);
provider = new PythonModelProvider();
Object[] children1 = provider.getChildren(project);
assertEquals(1, children1.length);
assertTrue("Expected source folder. Received: " + children1[0], children1[0] instanceof PythonSourceFolder);
f.mkdir();
f1.mkdir();
f2.mkdir();
try {
FolderStub source2FolderFile = new FolderStub(project, f);
FolderStub source2FolderChild = new FolderStub(project, source2FolderFile, f1);
FolderStub source2FolderReChild = new FolderStub(project, source2FolderChild, f2);
Set set = new HashSet();
set.add(source2FolderReChild);
provider.interceptAdd(new PipelinedShapeModification(source2FolderChild, set));
assertEquals(1, set.size());
PythonFolder c = (PythonFolder) set.iterator().next();
PythonSourceFolder sourceFolder = c.getSourceFolder();
assertTrue(sourceFolder instanceof PythonSourceFolder);
set.clear();
set.add(source2FolderChild);
provider.interceptRemove(new PipelinedShapeModification(source2FolderFile, set));
assertTrue(set.iterator().next() instanceof PythonFolder);
// System.out.println(set);
set.clear();
set.add(source2FolderReChild);
provider.interceptAdd(new PipelinedShapeModification(source2FolderChild, set));
assertTrue(set.iterator().next() instanceof PythonFolder);
// System.out.println(set);
set.clear();
set.add(source2FolderChild);
provider.interceptRemove(new PipelinedShapeModification(source2FolderFile, set));
assertTrue(set.iterator().next() instanceof PythonFolder);
// System.out.println(set);
set.clear();
set.add(source2FolderReChild);
provider.interceptAdd(new PipelinedShapeModification(source2FolderChild, set));
assertTrue(set.iterator().next() instanceof PythonFolder);
// System.out.println(set);
} finally {
f2.delete();
f1.delete();
f.delete();
}
}
public void testWorkingSetsTopLevel() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"); //root is the source
PythonNature nature = createNature(pythonPathSet);
WorkspaceRootStub workspaceRootStub = new WorkspaceRootStub();
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature);
workspaceRootStub.addChild(project);
project.setParent(workspaceRootStub);
ICallback<List<IWorkingSet>, IWorkspaceRoot> original = PythonModelProvider.getWorkingSetsCallback;
try {
final WorkingSetStub workingSetStub = new WorkingSetStub();
PythonModelProvider.getWorkingSetsCallback = new ICallback<List<IWorkingSet>, IWorkspaceRoot>() {
public List<IWorkingSet> call(IWorkspaceRoot arg) {
ArrayList<IWorkingSet> ret = new ArrayList<IWorkingSet>();
ret.add(workingSetStub);
return ret;
}
};
provider = new PythonModelProvider();
provider.topLevelChoice.rootMode = TopLevelProjectsOrWorkingSetChoice.WORKING_SETS;
//--- check children for the workspace (projects changed for working sets)
HashSet<Object> currentChildren = new HashSet<Object>();
currentChildren.add(project); //the project is changed for the workspace.
provider.getPipelinedChildren(workspaceRootStub, currentChildren);
HashSet<Object> expectedChildren = new HashSet<Object>();
expectedChildren.add(workingSetStub);
assertEquals(expectedChildren, currentChildren);
//--- now, check if we're able to get the children of the working set.
workingSetStub.addElement(project);
currentChildren = new HashSet<Object>();
provider.getPipelinedChildren(workingSetStub, currentChildren);
expectedChildren = new HashSet<Object>();
expectedChildren.add(project);
assertEquals(expectedChildren, currentChildren);
//--- and at last, do it the other way around: from the children of a working set we must be able to
//get the working set
currentChildren = new HashSet<Object>();
//the project has the workspace root as its 'default' parent. Let's change it for the working set
//just a note: working sets can have many elements as their direct children (such as folders and files)
//so, it's not just a matter of getting the parent if it's a project)!!!
assertEquals(workingSetStub, provider.getPipelinedParent(project, workspaceRootStub));
assertEquals(workingSetStub, provider.getParent(project));
} finally {
PythonModelProvider.getWorkingSetsCallback = original;
}
}
}